#include "buzzer_driver.h"
#include "gd32f4xx_gpio.h"
#include "systick.h"
#include "single_btn_driver.h"
#include "nixie_driver.h"

void buzzer_driver_config(void)
{
    // 外设时钟使能
    rcu_periph_clock_enable(RCU_GPIOB);

    // buzzer引脚配置
    // 输出模式,推挽输出,默认低电平
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, BUZZER_PIN);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, BUZZER_PIN);
    gpio_bit_reset(GPIOB, BUZZER_PIN);
}

/**
 * 按照指定频率播放指定时间
 */
void buzzer_driver_play(uint32_t freq, uint32_t ms)
{
    if (freq <= 0U)
        return;

    if (ms <= 0U)
        return;

    // 周期时间
    uint32_t cycle_duration = buzzer_driver_cycle_duration(freq);
    uint32_t count = (ms * 1000U) / cycle_duration;

    while (count)
    {
        buzzer_driver_vibrate(cycle_duration);
        count--;
    }
}

/**
 * 按照周期时间,振动一个周期
 */
void buzzer_driver_vibrate(uint32_t us)
{
    gpio_bit_set(GPIOB, BUZZER_PIN);
    delay_1us(us >> 1);
    // nixie_driver_delay(us >> 1);
    gpio_bit_reset(GPIOB, BUZZER_PIN);
    delay_1us(us >> 1);
    // nixie_driver_delay(us >> 1);
}

void buzzer_driver_vibrate_by_freq(uint32_t freq)
{
    uint32_t duration = buzzer_driver_cycle_duration(freq);
    buzzer_driver_vibrate(duration);
}

/**
 * 按照指定频率,与给定delay1us的函数
 */
void buzzer_driver_vibrate_by_freq_with_delay(uint32_t freq, void (*delay)(uint32_t))
{
    uint32_t duration = buzzer_driver_cycle_duration(freq);
    buzzer_driver_vibrate_with_dalay(duration, delay);
}

void buzzer_driver_vibrate_with_dalay(uint32_t us, void (*delay)(uint32_t))
{
    gpio_bit_set(GPIOB, BUZZER_PIN);
    delay(us >> 1);

    gpio_bit_reset(GPIOB, BUZZER_PIN);
    delay(us >> 1);
}

/**
 * 每个周期的时间
 */
uint32_t buzzer_driver_cycle_duration(uint32_t freq)
{
    return 1000000 / freq;
}

//
void buzzer_driver_test(void)
{
    uint8_t btns = single_btn_driver_get_all_status();
    if (btns & 0b1u)
    {
        buzzer_driver_vibrate(523);
    }
    if (btns & (0b1u << 1))
    {
        buzzer_driver_vibrate(587);
    }

    if (btns & (0b1u << 2))
    {
        buzzer_driver_vibrate(659);
    }
    if (btns & (0b1u << 3))
    {
        buzzer_driver_vibrate(698);
    }
}
